package ece1779.ec2;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.Serializable;

import sun.misc.IOUtils;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

public class Config {
	
	private static final String configFileName = "config";
	private static final String bucketName = "s3ece1779";
	
	
	private BasicAWSCredentials awsCredentials;
	private PrintWriter out;
	
	public ConfigData data;
	private String path;
	
	public Config(BasicAWSCredentials _awsCredentials, PrintWriter _out, String _path){
		data = new ConfigData();
		awsCredentials = _awsCredentials;
		out = _out;
		path = _path;
		loadConfig(s3GetFile(configFileName));
	}
	
    public InputStream s3GetFile(String key){
    	
    	AmazonS3 s3 = new AmazonS3Client(awsCredentials);
    	
    	S3Object getObject = null;
        try {
        	getObject = s3.getObject(bucketName, key);

        } catch (AmazonServiceException ase) {
        	processAmazonServiceException(ase);
        } catch (AmazonClientException ace) {
        	processAmazonClientException(ace);
        }
       
        return getObject.getObjectContent();
    }
    
    public void s3SaveFile(File file, String key) throws IOException {
    	AmazonS3 s3 = new AmazonS3Client(awsCredentials);
        
        String bucketName = "s3ece1779";
 
        try {
            s3.putObject(new PutObjectRequest(bucketName, key, file));
            s3.setObjectAcl(bucketName, key, CannedAccessControlList.PublicRead);

        } catch (AmazonServiceException ase) {
        	processAmazonServiceException(ase);
        } catch (AmazonClientException ace) {
        	processAmazonClientException(ace);
        }
    }

    public void storeConfig(){
			try {
				FileOutputStream fos = new FileOutputStream(path + configFileName);
	    		ObjectOutputStream oos = new ObjectOutputStream(fos);
	    		oos.writeObject(data);
	    		oos.flush();
	    		oos.close();
	    		fos.close();
	    		File config = new File(path + configFileName);
				s3SaveFile(config, configFileName);
			} catch (IOException e) {
				e.printStackTrace();
			}
    }
    
    private void loadConfig(InputStream is){
		try {
    		ObjectInputStream ois = new ObjectInputStream(is);
    		data = (ConfigData) ois.readObject();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    }
    
    private void resetDefaults(){
    	data.growTreshold = 60;
    	data.shrinkTreshold = 5;
    	data.growMultiplier = 2;
    	data.shrinkMultiplier = 3;
    	storeConfig();
    }
    
    public String toString(){
    	return "GT:" + data.growTreshold +  " ST:" + data.shrinkTreshold + " GM:" + data.growMultiplier + " SM:" + data.shrinkMultiplier; 
    }
    private void processAmazonServiceException(AmazonServiceException ase){
    	if (out != null){
	    	out.println("Caught an AmazonServiceException, which means your request made it "
	                + "to Amazon S3, but was rejected with an error response for some reason.");
	        out.println("Error Message:    " + ase.getMessage());
	        out.println("HTTP Status Code: " + ase.getStatusCode());
	        out.println("AWS Error Code:   " + ase.getErrorCode());
	        out.println("Error Type:       " + ase.getErrorType());
	        out.println("Request ID:       " + ase.getRequestId());
    	}
    }
    
    private void processAmazonClientException(AmazonClientException ace) {
    	if (out != null){
	        out.println("Caught an AmazonClientException, which means the client encountered "
	                + "a serious internal problem while trying to communicate with S3, "
	                + "such as not being able to access the network.");
	        out.println("Error Message: " + ace.getMessage());
    	}
    }
}
